package com.augmentum.oes.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.augmentum.oes.Constants;
import com.augmentum.oes.dao.ExamDao;
import com.augmentum.oes.dao.QuestionBackupDao;
import com.augmentum.oes.dao.QuestionDao;
import com.augmentum.oes.exception.ParameterException;
import com.augmentum.oes.exception.ServiceException;
import com.augmentum.oes.model.Exam;
import com.augmentum.oes.model.Pagination;
import com.augmentum.oes.model.Question;
import com.augmentum.oes.model.QuestionBack;
import com.augmentum.oes.model.SortStatusEnum;
import com.augmentum.oes.service.ExamService;
import com.augmentum.oes.util.Regex;
import com.augmentum.oes.util.StringUtil;

@Service
public class ExamServiceImpl implements ExamService {

    private static final int PAGE_SIZE = 20;
    private static final String NO_DATA = "There is no query to the data!";
    private static final String TOTAL_QUESTION_MSG = "Sorry,the question is not enough in the system!";
    private static final String ID_REQUIRED = "Exam id is required!";

    private static final int ARRAY_LENGTH = 1;
    private static final int DEFAULT_QUANTITY = 0;

    @Resource
    private ExamDao examDao;

    @Resource
    private QuestionDao questionDao;

    @Resource
    private QuestionBackupDao questionBackDao;

    public ExamServiceImpl() {
        super();
    }

    @Override
    public List<Exam> getList(Pagination pagination, SortStatusEnum sort, String sortField, String keyWord)
            throws ServiceException {

        if (!StringUtil.isEmpty(keyWord)) {
            keyWord = Regex.regex(keyWord);
        }
        if (pagination.getPageSize() > 20) {
            pagination.setPageSize(PAGE_SIZE);
        }
        List<Exam> list = examDao.getList(pagination, sort, sortField, keyWord);

        if (list == null) {
            throw new ServiceException(NO_DATA);
        }
        return list;
    }

    @Override
    public String saveExam(Exam exam) throws ParameterException {
        String msgString = null;
        int totalQuestion = questionDao.getTotalCount("");
        if (totalQuestion < exam.getQuestionQuantity()) {
            exam.setDraft(true);
            exam.setQuestionQuantity(DEFAULT_QUANTITY);
            msgString = TOTAL_QUESTION_MSG;
        }
        exam.setDescription(exam.getDescription().trim());
        exam.setTotalScore(exam.getQuestionPoints() * exam.getQuestionQuantity());
        examDao.save(exam);
        return msgString;
    }

    @Override
    public List<Exam> getQuestionByExamId(int id) {
        return examDao.getQuestionByExamId(id);
    }

    @Override
    public Exam getById(int id) {
        return examDao.getById(id);
    }

    @Override
    public String updateExam(Exam exam) {
        Exam oldExam = examDao.getById(exam.getId());
        String msgString = null;
        int totalQuestion = questionDao.getTotalCount("");
        if (totalQuestion < exam.getQuestionQuantity()) {
            msgString = TOTAL_QUESTION_MSG;
        } else {
            if (oldExam.getQuestionQuantity() > exam.getQuestionQuantity()) {
                questionBackDao.randToDelete(oldExam.getId(),
                        oldExam.getQuestionQuantity() - exam.getQuestionQuantity());
                exam.setDraft(false);
            } else if (oldExam.getQuestionQuantity() < exam.getQuestionQuantity()) {
                List<Question> list = questionDao.getRandomQuestion(exam.getQuestionQuantity()
                        - oldExam.getQuestionQuantity());
                List<QuestionBack> backlist = new ArrayList<QuestionBack>();
                for (Question question : list) {
                    QuestionBack questionBack = new QuestionBack();
                    questionBack.setQuestion(question.getQuestion());
                    questionBack.setAnswerA(question.getAnswerA());
                    questionBack.setAnswerB(question.getAnswerB());
                    questionBack.setAnswerC(question.getAnswerC());
                    questionBack.setAnswerD(question.getAnswerD());
                    questionBack.setAnswer(question.getAnswer());
                    questionBack.setExam(exam);
                    backlist.add(questionBack);
                }
                exam.setDraft(false);
                questionBackDao.randToAdd(backlist);
            }
            examDao.update(exam);
        }
        return msgString;
    }

    @Override
    public void dropById(String[] idStr) throws ParameterException {
        ParameterException parameterException = new ParameterException();
        if (idStr.length < ARRAY_LENGTH) {
            parameterException.addErrorMessage(Constants.ERROR_MESSAGE, ID_REQUIRED);
        }
        if (parameterException.isErrorMessage()) {
            throw parameterException;
        }
        examDao.dropById(idStr);
    }

    @Override
    public List<Exam> searchByDate(String start, String end) {
        return examDao.searchByDate(start, end);
    }

}
